//
// Created by void on 24-1-14.
//

#include "TcpServer.h"
struct TcpServer* tcpServerInit(unsigned short port, int threadNum) {
    struct TcpServer* tcp = (struct TcpServer*) malloc(sizeof (struct TcpServer));
    tcp->listener = listenerInit(port);
    tcp->mainLoop = eventLoopInit();
    tcp->threadNum = threadNum;
    tcp->threadPool = threadPoolInit(tcp->mainLoop, threadNum);
    return tcp;
}

struct Listener* listenerInit(unsigned short port){
    struct Listener* listener = (struct Listener*) malloc(sizeof (struct Listener));

    int lfd = socket(AF_INET, SOCK_STREAM, 0);
    if(lfd == -1) {
        perror("socket");
        exit(0);
    }

    int opt = 1;
    int ret = setsockopt(lfd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof (opt));
    if(-1 == ret) {
        perror("socketopt");
        exit(0);
    }

    struct sockaddr_in addr;
    addr.sin_family = AF_INET;
    addr.sin_port = htons(port);
    addr.sin_addr.s_addr = INADDR_ANY;
    ret = bind(lfd, (struct sockaddr*)&addr, sizeof (addr));
    if(-1 == ret) {
        perror("bind");
        exit(0);
    }

    ret = listen(lfd, 128);
    if(-1 == ret) {
        perror("listen");
        exit(0);
    }

    listener->lfd = lfd;
    listener->port = port;
    return listener;
}
#include <stdio.h>
int acceptConnection(void *arg) {
    struct TcpServer* server = (struct TcpServer*)arg;

    int cfd = accept(server->listener->lfd, NULL, NULL);

    struct EventLoop* evLoop = takeWorkerEventLoop(server->threadPool);

    tcpConnectionInit(cfd, evLoop);

    return 0;
}

void tcpServerRun(struct TcpServer* server) {
    threadPoolRun(server->threadPool);
    struct Channel* channel = channelInit(server->listener->lfd,
            ReadEvent, acceptConnection,
            NULL, NULL, server);
    eventLoopAddTask(server->mainLoop, channel, ADD);

    eventLoopRun(server->mainLoop);
}
